/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package facades;

import entities.Almacen;
import entities.AlmacenTienda;
import entities.LineaInventarioAlmacen;
import entities.ProductoTalla;
import entities.Tienda;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author damfercer
 */
@Stateless
public class AlmacenFacade extends AbstractFacade<Almacen> {
    private final Integer ALMACEN_VENTAS_ID=1;
    @PersistenceContext(unitName = "CorporatePU")
    private EntityManager em;
    @Inject
    LineaInventarioAlmacenFacade lineaInventarioFacade;
    
    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public AlmacenFacade() {
        super(Almacen.class);
    }
    
    public Almacen getAlmacenTransportista(){
        Almacen transportista=null;
        Query q=em.createNamedQuery("Almacen.findByTipoAlmacen");
        q.setParameter("idTipoAlmacen", 5);
        List<Almacen> almacenesTransportistas=q.getResultList();
        if(!almacenesTransportistas.isEmpty()){
            transportista=almacenesTransportistas.get(0);
        }
        return transportista;
    }
    
    public Almacen getAlmacenPerdidas(){
        Almacen perdidas=null;
        Query q=em.createNamedQuery("Almacen.findByTipoAlmacen");
        q.setParameter("idTipoAlmacen", 3);
        List<Almacen> almacenesPerdidas=q.getResultList();
        if(!almacenesPerdidas.isEmpty()){
            perdidas=almacenesPerdidas.get(0);
        }
        return perdidas;
    }
    
    public Almacen getAlmacenVentasAleatorioDeTienda(Tienda t){
        List<Almacen> almacenesVenta=new ArrayList<Almacen>();
        for (AlmacenTienda almacenTienda : t.getAlmacenTiendaList()) {
            Almacen almacen=almacenTienda.getAlmacen();
            if(almacen.getTipoAlmacen().getIdTipoAlmacen()==ALMACEN_VENTAS_ID){
                almacenesVenta.add(almacen);
            }
        }
        Random random=new Random();    
        Integer randomPos=random.nextInt(almacenesVenta.size());
        return almacenesVenta.get(randomPos);
    }
    
    
    public Almacen getAlmacenReservaAsociado(Almacen a){
        Almacen reserva=a;
        for (Almacen almacenReserva : a.getAlmacenList()) {
            if(almacenReserva.getTipoAlmacen().getIdTipoAlmacen()==2){
                reserva=almacenReserva;
                break;
            }
        }
        return reserva;
    }
    
    public Boolean esteAlmacenTieneProductoTallaYCantidad(Almacen almacen, ProductoTalla productoTalla, Integer cantidad){
        Boolean tieneLinea=false;
        LineaInventarioAlmacen lineaInventario=lineaInventarioFacade.getLineaInventarioDeAlmacen(almacen, productoTalla);
        if(lineaInventario!=null){
            tieneLinea=lineaInventario.getCantidad()>cantidad;
        }
        return tieneLinea;
    }
    
    
    public List<Almacen> getAlmacenesVentasConTodosLosProductosSinEsteAlmacen(Almacen a, Map<ProductoTalla, Integer> mapa){
        List<Almacen> almacenesQueCumplen=null;
        for(Almacen almacen : this.findAll()) {
            if(!almacen.equals(a) && almacen.getTipoAlmacen().getIdTipoAlmacen()==ALMACEN_VENTAS_ID){
                Boolean cumpleAlmacen=true;
                for (Entry<ProductoTalla,Integer> entry : mapa.entrySet()) {
                    ProductoTalla productoTalla=entry.getKey();
                    Integer cantidad=entry.getValue();
                    if(cantidad!=0){
                        cumpleAlmacen=cumpleAlmacen && esteAlmacenTieneProductoTallaYCantidad(almacen, productoTalla, cantidad);
                        if(!cumpleAlmacen){
                            break;
                        }
                    }
                }
                if(cumpleAlmacen){
                    if(almacenesQueCumplen==null){
                        almacenesQueCumplen=new ArrayList<Almacen>();
                    }
                    almacenesQueCumplen.add(almacen);
                }
            }
        }
        return almacenesQueCumplen;
    }
    
    
    public List<Almacen> getAlmacenesVentasConTodosLosProductos(Map<ProductoTalla, Integer> mapa){
        List<Almacen> almacenesQueCumplen=null;
        for(Almacen almacen : this.findAll()) {
            if(almacen.getTipoAlmacen().getIdTipoAlmacen()==ALMACEN_VENTAS_ID){
                Boolean cumpleAlmacen=true;
                for (Entry<ProductoTalla,Integer> entry : mapa.entrySet()) {
                    ProductoTalla productoTalla=entry.getKey();
                    Integer cantidad=entry.getValue();
                    if(cantidad!=0){
                        cumpleAlmacen=cumpleAlmacen && esteAlmacenTieneProductoTallaYCantidad(almacen, productoTalla, cantidad);
                        if(!cumpleAlmacen){
                            break;
                        }
                    }
                }
                if(cumpleAlmacen){
                    if(almacenesQueCumplen==null){
                        almacenesQueCumplen=new ArrayList<Almacen>();
                    }
                    almacenesQueCumplen.add(almacen);
                }
            }
        }
        return almacenesQueCumplen;
    }
    
    public Almacen getAlmacenVentasAleatorioConTodosLosProductosSinEsteAlmacen(Almacen a,Map<ProductoTalla, Integer> mapa){
        Random random=new Random();    
        Almacen almacenConTodosLosProductos=null;
        List<Almacen> almacenesConTodosLosProductos=getAlmacenesVentasConTodosLosProductosSinEsteAlmacen(a, mapa);
        if(almacenesConTodosLosProductos!=null && !almacenesConTodosLosProductos.isEmpty()){
            Integer randomPos=random.nextInt(almacenesConTodosLosProductos.size());
            almacenConTodosLosProductos=almacenesConTodosLosProductos.get(randomPos);
        }
        return almacenConTodosLosProductos;
    }
    
    public Almacen getAlmacenVentasAleatorioConTodosLosProductos(Map<ProductoTalla, Integer> mapa){
        Random random=new Random();    
        Almacen almacenConTodosLosProductos=null;
        List<Almacen> almacenesConTodosLosProductos=getAlmacenesVentasConTodosLosProductos(mapa);
        if(almacenConTodosLosProductos!=null && !almacenesConTodosLosProductos.isEmpty()){
            Integer randomPos=random.nextInt(almacenesConTodosLosProductos.size());
            almacenConTodosLosProductos=almacenesConTodosLosProductos.get(randomPos);
        }
        return almacenConTodosLosProductos;
    }
    
    public List<Almacen> getAlmacenesConTodosLosProductosAbstract(Almacen sinEsteAlmacen, Map<ProductoTalla,Integer> mapaProductos, List<Almacen> almacenesEnLosQueBuscar){
        List<Almacen> almacenesQueCumplen=null;
        for(Almacen almacen : almacenesEnLosQueBuscar) {
            if(sinEsteAlmacen==null || !almacen.equals(sinEsteAlmacen)){
                Boolean cumpleAlmacen=true;
                for (Entry<ProductoTalla,Integer> entry : mapaProductos.entrySet()) {
                    ProductoTalla productoTalla=entry.getKey();
                    Integer cantidad=entry.getValue();
                    if(cantidad!=0){
                        cumpleAlmacen=cumpleAlmacen && esteAlmacenTieneProductoTallaYCantidad(almacen, productoTalla, cantidad);
                        if(!cumpleAlmacen){
                            break;
                        }
                    }
                }
                if(cumpleAlmacen){
                    if(almacenesQueCumplen==null){
                        almacenesQueCumplen=new ArrayList<Almacen>();
                    }
                    almacenesQueCumplen.add(almacen);
                }
            }
                
        }
        return almacenesQueCumplen;
    }
    
    public Almacen getAlmacenAleatorioConTodosLosProductosAbstract(Almacen sinEsteAlmacen, Map<ProductoTalla,Integer> mapaProductos, List<Almacen> almacenesEnLosQueBuscar){
        Random random=new Random();    
        Almacen almacenConTodosLosProductos=null;
        List<Almacen> almacenesConTodosLosProductos=getAlmacenesConTodosLosProductosAbstract(sinEsteAlmacen,mapaProductos,almacenesEnLosQueBuscar);
        if(almacenesConTodosLosProductos!=null && !almacenesConTodosLosProductos.isEmpty()){
            Integer randomPos=random.nextInt(almacenesConTodosLosProductos.size());
            almacenConTodosLosProductos=almacenesConTodosLosProductos.get(randomPos);
        }
        return almacenConTodosLosProductos;
    }
    
    
    
}
